#include "types.h"

const uint64 SBI_SET_TIMER = 0;
const uint64 SBI_CONSOLE_PUTCHAR = 1;
const uint64 SBI_CONSOLE_GETCHAR = 2;
const uint64 SBI_SHUTDOWN = 8;


int inline sbi_ecall(uint64 which, uint64 arg0, uint64 arg1, uint64 arg2) {
    register uint64 a0 asm("a0") = arg0;
    register uint64 a1 asm("a1") = arg1;
    register uint64 a2 asm("a2") = arg2;
    register uint64 a7 asm("a7") = which;
    asm volatile("ecall"
                 : "=r"(a0)
                 : "r"(a0), "r"(a1), "r"(a2), "r"(a7)
                 : "memory");
    return a0;
}

// static int sbi_ecall(int64 ecall_type, int64 arg0, int64 arg1, int64 arg2) {
// 	int64 ret;
// 	asm volatile (
// 		"mv a7, %[ecall_type]\n"
// 		"mv a0, %[arg0]\n"
// 		"mv a1, %[arg1]\n"
// 		"mv a2, %[arg2]\n"
// 		"ecall\n"
// 		"mv %[ret], a7"
// 		: [ret] "=r" (ret)
// 		: [ecall_type] "r" (ecall_type), [arg0] "r" (arg0), [arg1] "r" (arg1), [arg2] "r" (arg2)
// 		: "memory");
// 	return ret;
// }

void set_timer(uint64 time) {
	sbi_ecall(SBI_SET_TIMER, time, 0, 0);
}

void console_putchar(char ch) {
	sbi_ecall(SBI_CONSOLE_PUTCHAR, ch, 0, 0);
}

char console_getchar(void) {
	return sbi_ecall(SBI_CONSOLE_GETCHAR, 0, 0, 0);
}

void shutdown(void) {
	sbi_ecall(SBI_SHUTDOWN, 0, 0, 0);
}
